package com.example.web.service.impl;

import com.example.web.entity.User;
import com.example.web.entity.LoginRequest;
import com.example.web.entity.LoginResponse;
import com.example.web.mapper.UserMapper;
import com.example.web.mapper.UserRoleMapper;
import com.example.web.service.UserService;
import com.example.web.utils.JwtUtils;
import com.example.web.utils.PasswordEncoder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private PasswordEncoder md5PasswordEncoder;
    
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        if (loginRequest == null || StringUtils.isBlank(loginRequest.getUsername()) 
            || StringUtils.isBlank(loginRequest.getPassword())) {
            throw new RuntimeException("用户名和密码不能为空");
        }
        
        // 根据用户名查找用户
        User user = userMapper.findByUsername(loginRequest.getUsername());
        
        if (user == null) {
            System.out.println("DEBUG: 用户不存在，用户名: " + loginRequest.getUsername());
            throw new RuntimeException("用户名或密码错误");
        }
        
        System.out.println("DEBUG: 找到用户: " + user.getUsername());
        System.out.println("DEBUG: 数据库密码: " + user.getPassword());
        System.out.println("DEBUG: 输入密码: " + loginRequest.getPassword());
        
        // 验证密码
        boolean passwordMatches = md5PasswordEncoder.matches(loginRequest.getPassword(), user.getPassword());
        System.out.println("DEBUG: 密码验证结果: " + passwordMatches);
        
        if (!passwordMatches) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        if (user.getStatus() == 0) {
            throw new RuntimeException("用户已被禁用");
        }
        
        // 生成JWT token（包含用户ID）
        String token = jwtUtils.generateToken(user.getUsername(), user.getId());
        
        // 创建登录响应，不返回密码
        User userInfo = new User();
        userInfo.setId(user.getId());
        userInfo.setUsername(user.getUsername());
        userInfo.setName(user.getName());
        userInfo.setEmail(user.getEmail());
        userInfo.setStatus(user.getStatus());
        userInfo.setCreateTime(user.getCreateTime());
        userInfo.setUpdateTime(user.getUpdateTime());
        
        return new LoginResponse(token, userInfo);
    }

    @Override
    public User findByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        return userMapper.findByUsername(username);
    }

    @Override
    public User findById(Long id) {
        if (id == null) {
            return null;
        }
        return userMapper.findById(id);
    }

    @Override
    public boolean validateUser(String username, String password) {
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            return false;
        }
        
        User user = userMapper.findByUsername(username);
        if (user == null) {
            return false;
        }
        
        return md5PasswordEncoder.matches(password, user.getPassword()) && user.getStatus() == 1;
    }
    
    @Override
    public List<User> getAllUsers() {
        return userMapper.findAll();
    }
    
    @Override
    public Map<String, Object> getUserList(Integer page, Integer size, String username) {
        // 计算偏移量
        int offset = (page - 1) * size;
        
        // 查询用户列表
        List<User> users = userMapper.findUsersByPage(offset, size, username);
        // 清除密码字段
        users.forEach(user -> user.setPassword(null));
        
        // 查询总数
        Long total = userMapper.countUsers(username);
        
        // 封装结果
        Map<String, Object> result = new HashMap<>();
        result.put("records", users);
        result.put("total", total);
        result.put("page", page);
        result.put("size", size);
        result.put("pages", (total + size - 1) / size); // 计算总页数
        
        return result;
    }
    
    @Override
    public User createUser(User user) {
        if (user == null || StringUtils.isBlank(user.getUsername()) 
            || StringUtils.isBlank(user.getPassword())) {
            throw new RuntimeException("用户信息不完整");
        }
        
        // 验证姓名不能为空
        if (StringUtils.isBlank(user.getName())) {
            throw new RuntimeException("姓名不能为空");
        }
        
        // 检查用户名是否已存在
        User existingUser = userMapper.findByUsername(user.getUsername());
        if (existingUser != null) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 加密密码
        String encodedPassword = md5PasswordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);
        
        // 设置默认值
        if (user.getStatus() == null) {
            user.setStatus(1); // 默认启用
        }
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        userMapper.insert(user);
        
        // 返回的用户信息不包含密码
        user.setPassword(null);
        return user;
    }
    
    @Override
    public User updateUser(User user) {
        if (user == null || user.getId() == null) {
            throw new RuntimeException("用户ID不能为空");
        }
        
        User existingUser = userMapper.findById(user.getId());
        if (existingUser == null) {
            return null;
        }
        
        // 验证姓名不能为空
        if (StringUtils.isBlank(user.getName())) {
            throw new RuntimeException("姓名不能为空");
        }
        
        // 如果用户名发生变化，检查新用户名是否已存在
        if (!existingUser.getUsername().equals(user.getUsername())) {
            User userWithSameName = userMapper.findByUsername(user.getUsername());
            if (userWithSameName != null) {
                throw new RuntimeException("用户名已存在");
            }
        }
        
        // 如果提供了新密码，则进行加密
        if (StringUtils.isNotBlank(user.getPassword())) {
            String encodedPassword = md5PasswordEncoder.encode(user.getPassword());
            user.setPassword(encodedPassword);
        } else {
            // 如果没有提供密码，保持原密码
            user.setPassword(existingUser.getPassword());
        }
        
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
        
        // 返回的用户信息不包含密码
        user.setPassword(null);
        return user;
    }
    
    @Override
    public boolean deleteUser(Long id) {
        if (id == null) {
            return false;
        }
        
        User user = userMapper.findById(id);
        if (user == null) {
            return false;
        }
        
        // 删除用户前，先删除用户角色关联
        userRoleMapper.deleteUserRoleByUserId(id);
        
        userMapper.deleteById(id);
        return true;
    }
    
    @Override
    public List<Long> getRoleIdsByUserId(Long userId) {
        if (userId == null) {
            throw new RuntimeException("用户ID不能为空");
        }
        return userRoleMapper.getRoleIdsByUserId(userId);
    }
    
    @Override
    public List<String> getRolesByUserId(Long userId) {
        if (userId == null) {
            throw new RuntimeException("用户ID不能为空");
        }
        
        return userRoleMapper.getRoleCodesByUserId(userId);
    }
    
    @Override
    public boolean assignRolesToUser(Long userId, List<Long> roleIds) {
        if (userId == null) {
            throw new RuntimeException("用户ID不能为空");
        }
        
        // 验证用户是否存在
        User user = userMapper.findById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 先删除原有的角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);
        
        // 如果提供了新的角色列表，则添加新的关联
        if (roleIds != null && !roleIds.isEmpty()) {
            for (Long roleId : roleIds) {
                userRoleMapper.insertUserRole(userId, roleId);
            }
        }
        
        return true;
    }
}